package com.ccsoft.annoreflect.utils;

import com.ccsoft.annoreflect.anno.Table;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author chanchaw
 * @create 2022-09-24 12:27
 */
// 针对自定义注解 @Table 的工具类
public class AnnoTableUtils<T> {

    private static final String NO_TABLE_ANNOTATION = "没有找到注解@Table!";
    private static final String NO_SET_TABLE_NAME = "注解@Table没有设置表名称！";

    private static final String NO_SET_TABLE_FIELD = "要求实体类中至少有一个属性使用注解@TableField";
    private T record = null;
    private String tableName = "";
    private Field[] fields = null;

    private Class<?> clazz = null;

    private AnnoTableUtils(){ }

    public AnnoTableUtils(T record) {
        this.record = record;
        resolveAnnotation(record);
    }

    private void resolveAnnotation(T record){
        clazz = record.getClass();
        Table tableAnno = clazz.getAnnotation(Table.class);
        if(tableAnno == null) throw new RuntimeException(NO_TABLE_ANNOTATION);
        tableName = tableAnno.tableName();
        if(tableName == null || tableName.length()<=0) throw new RuntimeException(NO_SET_TABLE_NAME);

        // 获取属性
        fields = clazz.getDeclaredFields();
        if(fields == null || fields.length<=0) throw new RuntimeException(NO_SET_TABLE_FIELD);
    }

    public Object getFieldValue(T record,Field field){
        if(fields == null || fields.length<=0) throw new RuntimeException(NO_SET_TABLE_FIELD);
        String getterMethodName = getGetterMethodName(getGetterMethodName(field.getName()));

        Method getterMethod = null;
        try {
            getterMethod = clazz.getMethod(getterMethodName);
        } catch (NoSuchMethodException e) {
            return null;
        }

        Object ret = null;
        try {
            ret = getterMethod.invoke(record);
        } catch (IllegalAccessException e) {
            return null;
        } catch (InvocationTargetException e) {
            return null;
        }

        return ret;
    }

    private String getGetterMethodName(String fieldName){
        return "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
    }


}
